import React from 'react'
import {
  ActivityIndicator, Animated, Image, ImageSourcePropType, Text, View,
} from 'react-native'
import EStyleSheet from 'react-native-extended-stylesheet'
import Images from '@IMAGE'

export interface ToastProps {
  content: string | React.ReactNode
  duration?: number
  onClose?: () => void
  source?: ImageSourcePropType
  mask?: boolean
  type?: string
  onAnimationEnd?: () => void
}

export default class ToastContainer extends React.Component<ToastProps, any> {
  anim: Animated.CompositeAnimation | null

  static defaultProps = {
    duration: 3,
    mask: true,
    onClose() {},
  }

  constructor(props: ToastProps) {
    super(props)
    this.state = {
      fadeAnim: new Animated.Value(0),
    }
  }

  componentDidMount() {
    const { onAnimationEnd } = this.props
    const duration = this.props.duration as number
    const { timing } = Animated
    if (this.anim) {
      this.anim = null
    }
    const animArr = [
      timing(this.state.fadeAnim, {
        toValue: 1,
        duration: 200,
        useNativeDriver: true,
      }),
      Animated.delay(duration * 1000),
    ]
    if (duration > 0) {
      animArr.push(
        timing(this.state.fadeAnim, {
          toValue: 0,
          duration: 200,
          useNativeDriver: true,
        }),
      )
    }
    this.anim = Animated.sequence(animArr)
    this.anim.start(() => {
      if (duration > 0) {
        this.anim = null
        if (onAnimationEnd) {
          onAnimationEnd()
        }
      }
    })
  }

  componentWillUnmount() {
    if (this.anim) {
      this.anim.stop()
      this.anim = null
    }

    const { onClose } = this.props
    if (onClose) {
      onClose()
    }
  }

  render() {
    const {
      type = '', content, mask, source,
    } = this.props

    let iconDom: React.ReactElement<any> | null = null
    if (type === 'loading') {
      iconDom = (
        <ActivityIndicator
          animating
          style={[styles.centering]}
          color="white"
          size="large"
        />
      )
    } else if (type === 'info') {
      iconDom = null
    } else {
      const defaultIcon = type === 'fail' ? Images.common.error : Images.common.success
      iconDom = (
        <Image
          source={source || defaultIcon}
          style={styles.image}
        />
      )
    }

    return (
      <View
        style={[styles.container]}
        pointerEvents={mask ? undefined : 'box-none'}
      >
        <View style={[styles.innerContainer]}>
          <Animated.View style={{ opacity: this.state.fadeAnim }}>
            <View
              style={[
                styles.innerWrap,
                iconDom ? styles.iconToast : styles.textToast,
              ]}
            >
              {iconDom}
              {React.isValidElement(content) ? (
                content
              ) : (
                <Text style={[styles.content, iconDom && styles.contentCenter]}>{content}</Text>
              )}
            </View>
          </Animated.View>
        </View>
      </View>
    )
  }
}

ToastContainer.defaultProps = {
  duration: 3,
  mask: true,
  onClose() {},
}

const styles = EStyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    bottom: 0,
    right: 0,
    backgroundColor: 'transparent',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 999,
  },
  innerContainer: {
    backgroundColor: 'transparent',
  },
  innerWrap: {
    alignItems: 'center',
    backgroundColor: 'rgba(51, 51, 51, .95)',
    minWidth: 100,
  },
  iconToast: {
    width: 130,
    borderRadius: 12,
    paddingHorizontal: 16,
    paddingVertical: 13,
  },
  textToast: {
    borderRadius: 12,
    padding: 16,
  },
  content: {
    fontFamily: 'PingFangSC-Regular',
    fontSize: 14,
    fontWeight: '400',
    color: '$white',
    lineHeight: 20,
  },
  contentCenter: {
    textAlign: 'center',
  },
  image: {
    width: 48,
    height: 48,
    marginBottom: 16,
  },
  centering: {
    alignItems: 'center',
    justifyContent: 'center',
    padding: 8,
  },
})
